Data Mining Versuch Fahrzeugdaten¶
Autor: Prof. Dr. Johannes Maucher
Dozenten:
- Manuel Eberhardinger
- Florian Rupp
Studierende:
- Paul Michels (pm080)
- Erzan Gashi (eg053)
- Patryk Gadziomski (pg058)
Abgabe:¶
- Abzugeben ist das Jupyter Notebook mit dem verlangten Implementierungen und den entsprechenden Ausgaben.
- Das Notebook ist als .ipynb und als .html abzugeben.
- Klausurelevante Fragen sind Dokument "Fragenkatalog Datamining" zu finden.
- Antworten auf Fragen im Notebook, Diskussionen und Beschreibung der Ergebnisse sind optional (aber empfohlen) und werden nicht bewertet.
Einführung¶
Lernziele:¶
In diesem Versuch sollen Kenntnisse in folgenden Themen vermittelt werden:
- Datenimport und Datenexport von und zu
- Pandas Dataframes
- PostgreSQL Datenbanken
- Explorative Datenanalysen (EDA)
- Datenvisualisierung mit Matplotlib und plotly
- Überwachtes Lernen eines Klassifikationsmodells
- Überwachtes Lernen eines Regressionsmodells
- Evaluation von Klassifikationsmodellen
- Evaluation von Regressionsmodellen
- Kreuzvalidierung
- Hyperparameteroptimierung
Vorbereitung¶
Datenbankzugriff¶
- Installieren Sie PostgreSQL. Mit PostgreSQL sollte auch pgAdmin installiert werden. PgAdmin ist eine open-source Software für die Entwicklung und die Administration von PostgreSQL Datenbanken.
- Legen Sie über pgAdmin eine Datenbank für das Datamining-Praktikum an. In diese Datenbank werden alle in diesem Versuch relevanten Tabellen geschrieben.
- Für den Datenbankzugriff aus Python heraus wird in diesem Versuch SQLAlchemy eingesetzt. Machen Sie sich mit den Basics von SQLAlchemy vertraut, z.B. mithilfe von https://maucher.pages.mi.hdm-stuttgart.de/python4datascience/07DataBaseSQL.html#using-sqlalchemy-and-pandas, Abschnitt Using SQLAlchemy and Pandas.
Pandas Dataframe¶
Machen Sie sich mit den Grundlagen von Pandas vertraut.
Machine Learning¶
Machen Sie sich mit Entscheidungsbäumen, Random Forest, Single Layer Perzeptron und Multi Layer Perzeptron vertraut.
#conda install -y psycopg2
#!conda install -y -c anaconda sqlalchemy
import pandas as pd
from pandas.api.types import is_numeric_dtype
import numpy as np
from sqlalchemy import create_engine, inspect
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import classification_report, confusion_matrix, ConfusionMatrixDisplay
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error, mean_absolute_error, median_absolute_error, r2_score
from sklearn.linear_model import SGDRegressor
from sklearn.neural_network import MLPRegressor
# from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import RandomizedSearchCV
import matplotlib.pyplot as plt
import seaborn as sns
import plotly.express as px
import plotly.io as pio
# DIese Einstellung behept der Fehler, dass der plotly express scatter plot nicht in der HTML angezeigt wurde
pio.renderers.default='notebook'
# Diese EINstellung erlaubt uns alle Spalten eines pandas Dataframes auszugeben
pd.set_option('display.max_columns', None)
- Laden Sie die .csv-Datei in einen Pandas Dataframe.
df = pd.read_csv("./Fahrzeuginformationen.csv")
- Zeigen Sie für den angelegten Dataframe
- die ersten 10 Zeilen
df[:10]
| HST Benennung | HT Benennung | UT Benennung | Karosserie | Neupreis Brutto | Produktgruppe | Kraftstoffart | Schadstoffklasse | CCM | KW | HST PS | Getriebeart | Getriebe Benennung | Anzahl der Türen | Leergewicht | Zuladung | Zulässiges GG | Länge | Breite | Höhe | CO2-Emissionen | Min Energieeffizienzklasse | Antrieb | KSTA Motor | HST-HT Benennung | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Volkswagen | T6 Bus (SG)(05.2015->) | Multivan Trendline | Bs | 37962 | T5-Klasse Pkw | BS | E6 | 1896 | 112 | 154 | Schaltgetriebe | Getriebe 6-Gang | 4 | 2211 | 905 | 2967.615635 | 4852 | 1849 | 2019 | 218 | D | FA | STANDARD ->B | Volkswagen-T6 Bus (SG)(05.2015->) |
| 1 | Volkswagen | T6 Bus (SG)(05.2015->) | Multivan Comfortline | Bs | 45294 | T5-Klasse Pkw | BS | E6 | 1990 | 110 | 148 | Schaltgetriebe | Getriebe 6-Gang | 4 | 2243 | 753 | 3061.848723 | 4859 | 1827 | 1938 | 218 | D | FA | STANDARD ->B | Volkswagen-T6 Bus (SG)(05.2015->) |
| 2 | Volkswagen | T6 Bus (SG)(05.2015->) | Multivan Generation Six | Bs | 48675 | T5-Klasse Pkw | BS | E6 | 1943 | 110 | 150 | Schaltgetriebe | Getriebe 6-Gang | 4 | 2282 | 768 | 3018.887414 | 4788 | 1823 | 1990 | 218 | D | FA | STANDARD ->B | Volkswagen-T6 Bus (SG)(05.2015->) |
| 3 | Volkswagen | T6 Bus (SG)(05.2015->) | Multivan 70 Jahre Bulli | Bs | 47201 | T5-Klasse Pkw | BS | E6 | 2013 | 110 | 153 | Schaltgetriebe | Getriebe 6-Gang | 4 | 1954 | 1007 | 3096.198902 | 4927 | 1952 | 1935 | 210 | D | FA | STANDARD ->B | Volkswagen-T6 Bus (SG)(05.2015->) |
| 4 | Volkswagen | T6 Bus (SG)(05.2015->) | Multivan Join | Bs | 49453 | T5-Klasse Pkw | BS | E6 | 1945 | 112 | 152 | Schaltgetriebe | Getriebe 6-Gang | 4 | 1984 | 972 | 3068.590854 | 4916 | 1872 | 2026 | 210 | D | FA | STANDARD ->B | Volkswagen-T6 Bus (SG)(05.2015->) |
| 5 | Volkswagen | T6 Bus (SG)(05.2015->) | Multivan PanAmericana | Bs | 50795 | T5-Klasse Pkw | BS | E6 | 1938 | 109 | 154 | Schaltgetriebe | Getriebe 6-Gang | 4 | 2266 | 823 | 3046.890761 | 4886 | 1895 | 1933 | 210 | D | FA | STANDARD ->B | Volkswagen-T6 Bus (SG)(05.2015->) |
| 6 | Volkswagen | T6 Bus (SG)(05.2015->) | Multivan Edition | Bs | 51605 | T5-Klasse Pkw | BS | E6 | 1956 | 111 | 152 | Schaltgetriebe | Getriebe 6-Gang | 4 | 2165 | 724 | 2957.083511 | 4658 | 1946 | 1954 | 210 | D | FA | STANDARD ->B | Volkswagen-T6 Bus (SG)(05.2015->) |
| 7 | Volkswagen | T6 Bus (SG)(05.2015->) | Multivan Join lang | Bs | 54560 | T5-Klasse Pkw | BS | E6 | 1946 | 110 | 155 | Schaltgetriebe | Getriebe 6-Gang | 4 | 2127 | 960 | 3099.520813 | 5162 | 1883 | 2000 | 212 | D | FA | STANDARD ->B | Volkswagen-T6 Bus (SG)(05.2015->) |
| 8 | Volkswagen | T6 Bus (SG)(05.2015->) | Multivan Highline | Bs | 57729 | T5-Klasse Pkw | BS | E6 | 1966 | 106 | 154 | Schaltgetriebe | Getriebe 6-Gang | 4 | 2317 | 707 | 3033.083391 | 4994 | 1871 | 1980 | 218 | D | FA | STANDARD ->B | Volkswagen-T6 Bus (SG)(05.2015->) |
| 9 | Volkswagen | T6 Bus (SG)(05.2015->) | Multivan Business | Bs | 97850 | T5-Klasse Pkw | BS | E6 | 2029 | 106 | 152 | Schaltgetriebe | Getriebe 6-Gang | 4 | 2362 | 605 | 3006.976797 | 4948 | 1900 | 1931 | 218 | D | FA | STANDARD ->B | Volkswagen-T6 Bus (SG)(05.2015->) |
- die Größe (Anzahl Zeilen und Anzahl Spalten)
print(f'Rows: {df.shape[0]}; Columns: {df.shape[1]}')
Rows: 24194; Columns: 25
- die Anzahl der NaNs pro Spalte
an.
df.isna().sum()
HST Benennung 0 HT Benennung 0 UT Benennung 0 Karosserie 0 Neupreis Brutto 0 Produktgruppe 0 Kraftstoffart 0 Schadstoffklasse 0 CCM 0 KW 0 HST PS 0 Getriebeart 0 Getriebe Benennung 0 Anzahl der Türen 0 Leergewicht 0 Zuladung 0 Zulässiges GG 0 Länge 0 Breite 0 Höhe 0 CO2-Emissionen 0 Min Energieeffizienzklasse 0 Antrieb 0 KSTA Motor 0 HST-HT Benennung 0 dtype: int64
- Zeigen Sie mit der Pandas-Dataframe Methode
info(), den Datentyp aller Spalten an. Der Typ der SpalteCO2-Emissionenist tatsächlich kein numerischer Typ. Finden Sie heraus warum das so ist. Beheben Sie den Fehler und sorgen Sie dafür, dass auch diese Spalte einen numerischen Typ hat.
df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 24194 entries, 0 to 24193 Data columns (total 25 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 HST Benennung 24194 non-null object 1 HT Benennung 24194 non-null object 2 UT Benennung 24194 non-null object 3 Karosserie 24194 non-null object 4 Neupreis Brutto 24194 non-null int64 5 Produktgruppe 24194 non-null object 6 Kraftstoffart 24194 non-null object 7 Schadstoffklasse 24194 non-null object 8 CCM 24194 non-null int64 9 KW 24194 non-null int64 10 HST PS 24194 non-null int64 11 Getriebeart 24194 non-null object 12 Getriebe Benennung 24194 non-null object 13 Anzahl der Türen 24194 non-null int64 14 Leergewicht 24194 non-null int64 15 Zuladung 24194 non-null int64 16 Zulässiges GG 24194 non-null float64 17 Länge 24194 non-null int64 18 Breite 24194 non-null int64 19 Höhe 24194 non-null int64 20 CO2-Emissionen 24194 non-null object 21 Min Energieeffizienzklasse 24194 non-null object 22 Antrieb 24194 non-null object 23 KSTA Motor 24194 non-null object 24 HST-HT Benennung 24194 non-null object dtypes: float64(1), int64(10), object(14) memory usage: 4.6+ MB
Antwort:
Mit df['CO2-Emissionen'].astype(float) und pd.to_numeric(df['CO2-Emissionen']) wurde probiert die Werte der CO2-Emissionen als numerische Werte umzuwandeln, was in einer Fehlermedlung endete.
Die Werte der Spalte CO2-Emissionen werden als Typ object erkannt und lassen sich nicht in einen numerischen Wert umwandeln.
Wieso? : Manche der Werte sind als float-Werte gespeichert, jedoch mit einem Komma (,), was in Python nicht üblich ist. In Python werden float-Werte immer mit einem Punkt (.) definiert.
Lösung: Die Kommas in den Werten durch Punkte umtauschen und die Werte schlussendlich mit df['CO2-Emissionen'].astype(float) oder pd.to_numeric(df['CO2-Emissionen']) zu numerischne Werten (float) umwandeln.
df['CO2-Emissionen'] = [i.replace(',', '.') for i in df['CO2-Emissionen']]
df['CO2-Emissionen'] = pd.to_numeric(df['CO2-Emissionen'])
# OR df['CO2-Emissionen'] = df['CO2-Emissionen'].astype(float)
df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 24194 entries, 0 to 24193 Data columns (total 25 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 HST Benennung 24194 non-null object 1 HT Benennung 24194 non-null object 2 UT Benennung 24194 non-null object 3 Karosserie 24194 non-null object 4 Neupreis Brutto 24194 non-null int64 5 Produktgruppe 24194 non-null object 6 Kraftstoffart 24194 non-null object 7 Schadstoffklasse 24194 non-null object 8 CCM 24194 non-null int64 9 KW 24194 non-null int64 10 HST PS 24194 non-null int64 11 Getriebeart 24194 non-null object 12 Getriebe Benennung 24194 non-null object 13 Anzahl der Türen 24194 non-null int64 14 Leergewicht 24194 non-null int64 15 Zuladung 24194 non-null int64 16 Zulässiges GG 24194 non-null float64 17 Länge 24194 non-null int64 18 Breite 24194 non-null int64 19 Höhe 24194 non-null int64 20 CO2-Emissionen 24194 non-null float64 21 Min Energieeffizienzklasse 24194 non-null object 22 Antrieb 24194 non-null object 23 KSTA Motor 24194 non-null object 24 HST-HT Benennung 24194 non-null object dtypes: float64(2), int64(10), object(13) memory usage: 4.6+ MB
- Schreiben Sie den im vorigen Schritt angepassten Dataframe mit der Pandas Methode
to_sql()in eine Datenbanktabelle mit dem Namenvehicledata.
conn_str = 'postgresql://postgres:1234@localhost:5432/postgres'
engine = create_engine(conn_str).connect()
inspec = inspect(engine)
df.to_sql(name = 'vehicledata', con=engine, if_exists='replace')
print(inspec.has_table("vehicledata"))
True
Exemplarische Datenbankabfragen¶
- Verwenden Sie Pandas Dataframe Methode
read_sql_query()um 3 für Sie interessante Datenbankabfragen zu implementieren. Die Resultate der Abfragen werden in einen Pandas Dataframe geschrieben. Zeigen Sie diese an.
abfrage_1 = pd.read_sql_query('''SELECT "Produktgruppe" FROM "vehicledata"''', engine)
abfrage_1
| Produktgruppe | |
|---|---|
| 0 | T5-Klasse Pkw |
| 1 | T5-Klasse Pkw |
| 2 | T5-Klasse Pkw |
| 3 | T5-Klasse Pkw |
| 4 | T5-Klasse Pkw |
| ... | ... |
| 24189 | Van |
| 24190 | Van |
| 24191 | Van |
| 24192 | Van |
| 24193 | Van |
24194 rows × 1 columns
abfrage_2 = pd.read_sql_query('''SELECT * FROM "vehicledata" WHERE "Produktgruppe" = 'Van' ''', engine)
abfrage_2
| index | HST Benennung | HT Benennung | UT Benennung | Karosserie | Neupreis Brutto | Produktgruppe | Kraftstoffart | Schadstoffklasse | CCM | KW | HST PS | Getriebeart | Getriebe Benennung | Anzahl der Türen | Leergewicht | Zuladung | Zulässiges GG | Länge | Breite | Höhe | CO2-Emissionen | Min Energieeffizienzklasse | Antrieb | KSTA Motor | HST-HT Benennung | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 22112 | Dacia | Lodgy (04.2012->) | Comfort | Van | 13113 | Van | 06 | E6 | 1591 | 82 | 80 | Schaltgetriebe | Getriebe 5-Gang | 5 | 1293 | 610 | 1785.543416 | 4458 | 1734 | 1726 | 152.0 | E | FA | BI_LPG ->B | Dacia-Lodgy (04.2012->) |
| 1 | 22101 | Dacia | Lodgy (04.2012->) | Ambiance | Van | 11836 | Van | 06 | E6 | 1610 | 74 | 99 | Schaltgetriebe | Getriebe 5-Gang | 5 | 1308 | 559 | 1757.500000 | 4498 | 1838 | 1691 | 139.0 | D | FA | BI_LPG ->B | Dacia-Lodgy (04.2012->) |
| 2 | 22102 | Dacia | Lodgy (04.2012->) | Essential | Van | 12027 | Van | 06 | E6 | 1596 | 76 | 98 | Schaltgetriebe | Getriebe 5-Gang | 5 | 1267 | 649 | 1799.967224 | 4520 | 1733 | 1736 | 139.0 | D | FA | BI_LPG ->B | Dacia-Lodgy (04.2012->) |
| 3 | 22104 | Dacia | Lodgy (04.2012->) | Laureate | Van | 12810 | Van | 06 | E6 | 1606 | 73 | 100 | Schaltgetriebe | Getriebe 5-Gang | 5 | 1279 | 581 | 1852.282920 | 4704 | 1770 | 1676 | 139.0 | D | FA | BI_LPG ->B | Dacia-Lodgy (04.2012->) |
| 4 | 22105 | Dacia | Lodgy (04.2012->) | Comfort | Van | 13590 | Van | 06 | E6 | 1568 | 75 | 105 | Schaltgetriebe | Getriebe 5-Gang | 5 | 1273 | 647 | 1835.243423 | 4296 | 1745 | 1696 | 139.0 | D | FA | BI_LPG ->B | Dacia-Lodgy (04.2012->) |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 305 | 24189 | Ford | Galaxy (CDR)(2015->) | Titanium | Van | 48042 | Van | D | 6T | 2036 | 172 | 235 | Automatikgetriebe | Getriebe Automatik - Typ: 8F57 (8-Stufen) | 5 | 1755 | 798 | 2674.077424 | 4756 | 1911 | 1779 | 158.0 | B | FA | STANDARD ->D | Ford-Galaxy (CDR)(2015->) |
| 306 | 24190 | Ford | Galaxy (CDR)(2015->) | Titanium | Van | 48979 | Van | D | 6T | 1974 | 180 | 241 | Automatikgetriebe | Getriebe Automatik - Typ: 8F57 (8-Stufen) | 5 | 1770 | 775 | 2599.765400 | 4605 | 1977 | 1738 | 162.0 | B | FA | STANDARD ->D | Ford-Galaxy (CDR)(2015->) |
| 307 | 24191 | Ford | S-Max (CDR)(2015->) | ST-Line | Van | 50849 | Van | D | 6T | 2018 | 177 | 240 | Automatikgetriebe | Getriebe Automatik - Typ: 8F57 (8-Stufen) | 5 | 1763 | 804 | 2546.332693 | 5033 | 2011 | 1592 | 153.0 | B | FA | STANDARD ->D | Ford-S-Max (CDR)(2015->) |
| 308 | 24192 | Ford | S-Max (CDR)(2015->) | Vignale | Van | 52973 | Van | D | 6T | 1968 | 182 | 238 | Automatikgetriebe | Getriebe Automatik - Typ: 8F57 (8-Stufen) | 5 | 1704 | 820 | 2504.075063 | 4795 | 1941 | 1602 | 153.0 | B | FA | STANDARD ->D | Ford-S-Max (CDR)(2015->) |
| 309 | 24193 | Ford | Galaxy (CDR)(2015->) | Vignale | Van | 55797 | Van | D | 6T | 2019 | 179 | 239 | Automatikgetriebe | Getriebe Automatik - Typ: 8F57 (8-Stufen) | 5 | 1769 | 821 | 2558.819988 | 5022 | 1865 | 1771 | 162.0 | B | FA | STANDARD ->D | Ford-Galaxy (CDR)(2015->) |
310 rows × 26 columns
abfrage_3 = pd.read_sql_query('''SELECT "CO2-Emissionen","Produktgruppe" FROM "vehicledata" WHERE "CO2-Emissionen" = '92' ''', engine)
abfrage_3
| CO2-Emissionen | Produktgruppe | |
|---|---|---|
| 0 | 92.0 | Cabrio bis Kompaktklasse |
| 1 | 92.0 | untere Mittelklasse / Kompaktklasse |
| 2 | 92.0 | untere Mittelklasse / Kompaktklasse |
| 3 | 92.0 | untere Mittelklasse / Kompaktklasse |
| 4 | 92.0 | Kleinwagen |
| ... | ... | ... |
| 61 | 92.0 | untere Mittelklasse / Kompaktklasse |
| 62 | 92.0 | untere Mittelklasse / Kompaktklasse |
| 63 | 92.0 | untere Mittelklasse / Kompaktklasse |
| 64 | 92.0 | untere Mittelklasse / Kompaktklasse |
| 65 | 92.0 | kleine SUV / Geländewagen |
66 rows × 2 columns
Data Exploration¶
- Zeigen Sie für alle Spalten die Anzahl der unterschiedlichen Werte in dieser Spalte an.
df.nunique()
HST Benennung 42 HT Benennung 617 UT Benennung 3782 Karosserie 22 Neupreis Brutto 19739 Produktgruppe 28 Kraftstoffart 14 Schadstoffklasse 4 CCM 2197 KW 428 HST PS 560 Getriebeart 2 Getriebe Benennung 103 Anzahl der Türen 4 Leergewicht 1833 Zuladung 1208 Zulässiges GG 23919 Länge 2342 Breite 651 Höhe 1203 CO2-Emissionen 279 Min Energieeffizienzklasse 8 Antrieb 3 KSTA Motor 6 HST-HT Benennung 617 dtype: int64
- Benutzen Sie die Pandas Dataframe Methode
describe()um sämtliche deskriptiven Statistiken anzuzeigen.
df.describe()
| Neupreis Brutto | CCM | KW | HST PS | Anzahl der Türen | Leergewicht | Zuladung | Zulässiges GG | Länge | Breite | Höhe | CO2-Emissionen | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| count | 24194.000000 | 24194.000000 | 24194.000000 | 24194.000000 | 24194.000000 | 24194.000000 | 24194.000000 | 24194.000000 | 24194.000000 | 24194.000000 | 24194.000000 | 24194.000000 |
| mean | 40301.051790 | 1851.156361 | 126.653798 | 172.273126 | 4.480656 | 1588.890303 | 578.716211 | 2134.695183 | 4560.681905 | 1835.296478 | 1579.427503 | 135.869906 |
| std | 22037.781929 | 616.193218 | 60.835718 | 82.667899 | 0.880526 | 367.170624 | 191.292064 | 524.077515 | 412.813020 | 93.258553 | 219.588359 | 33.439398 |
| min | 6835.000000 | 831.000000 | 42.000000 | 51.000000 | 2.000000 | 29.000000 | 58.000000 | 0.000000 | 2571.000000 | 1394.000000 | 1180.000000 | 8.500000 |
| 25% | 26910.000000 | 1482.000000 | 88.000000 | 120.000000 | 4.000000 | 1381.000000 | 483.000000 | 1872.562390 | 4339.000000 | 1782.000000 | 1446.000000 | 115.000000 |
| 50% | 36720.000000 | 1941.000000 | 111.000000 | 151.000000 | 5.000000 | 1555.000000 | 547.000000 | 2075.265444 | 4575.000000 | 1829.000000 | 1502.000000 | 130.000000 |
| 75% | 47632.250000 | 2011.000000 | 141.000000 | 192.000000 | 5.000000 | 1745.000000 | 615.000000 | 2319.881506 | 4801.000000 | 1883.000000 | 1647.000000 | 153.000000 |
| max | 287347.000000 | 6706.000000 | 511.000000 | 705.000000 | 5.000000 | 10365.000000 | 7726.000000 | 15295.850636 | 6958.000000 | 2293.000000 | 3023.000000 | 397.000000 |
- Legen Sie eine Liste
numeric_featuresan, welche nur die Spaltennamen der numerischen Spalten enthält.
numeric_features = [i for i in df.columns.values if is_numeric_dtype(df[i]) == True]
numeric_features
['Neupreis Brutto', 'CCM', 'KW', 'HST PS', 'Anzahl der Türen', 'Leergewicht', 'Zuladung', 'Zulässiges GG', 'Länge', 'Breite', 'Höhe', 'CO2-Emissionen']
- Schreiben Sie die Namen aller nicht-numerischen Spalten in eine Liste
categoric_features.
categoric_features = [i for i in df.columns.values if is_numeric_dtype(df[i]) == False]
categoric_features
['HST Benennung', 'HT Benennung', 'UT Benennung', 'Karosserie', 'Produktgruppe', 'Kraftstoffart', 'Schadstoffklasse', 'Getriebeart', 'Getriebe Benennung', 'Min Energieeffizienzklasse', 'Antrieb', 'KSTA Motor', 'HST-HT Benennung']
- Visualisieren Sie für die Spalten
HST_Benennung,Neupreis Brutto,CO2-EmissionenundProduktgruppedie Verteilung der Werte in einem Barplot bzw. Histogramm.
df_for_plot_hst = df['HST Benennung'].value_counts()
df_for_plot_neupreis = df['Neupreis Brutto'].value_counts()
df_for_plot_co2 = df['CO2-Emissionen'].value_counts()
df_for_plot_produkt = df['Produktgruppe'].value_counts()
fig, axes = plt.subplots(nrows=1, ncols=2)
df_for_plot_hst.plot(ax=axes[0], kind='bar', title='HST Benennung / BAR', figsize=(15, 10))
df_for_plot_hst.plot(ax=axes[1], kind='hist', title='HST Benennung / HIST', figsize=(15, 10))
fig.set_figheight(5)
fig.set_figwidth(15)
plt.show()
fig2, axes = plt.subplots(nrows=1, ncols=2)
# Wir benutzen hier nur jeeils die ersten 100 Reihen, da der plot ansonsten zu unüberischtlich wird
# Wenn gewünscht wird alle Reihen auszugeben: "[:100]" aus den beiden unteren Zeilen entfernen
df_for_plot_neupreis[:100].plot(ax=axes[0], kind='bar', title='Neupreis Brutto / BAR', figsize=(15, 10))
df_for_plot_neupreis[:100].plot(ax=axes[1], kind='hist', title='Neupreis Brutto / HIST', figsize=(15, 10))
fig2.set_figheight(5)
fig2.set_figwidth(15)
plt.show()
fig3, axes = plt.subplots(nrows=1, ncols=2)
df_for_plot_co2.plot(ax=axes[0], kind='bar', title='CO2 Emission / BAR', figsize=(15, 10))
df_for_plot_co2.plot(ax=axes[1], kind='hist', title='CO2 Emission / HIST', figsize=(15, 10))
fig3.set_figheight(5)
fig3.set_figwidth(15)
plt.show()
fig4, axes = plt.subplots(nrows=1, ncols=2)
df_for_plot_produkt.plot(ax=axes[0], kind='bar', title='Produktgruppe / BAR', figsize=(15, 10))
df_for_plot_produkt.plot(ax=axes[1], kind='hist', title='Produktgruppe / HIST', figsize=(15, 10))
fig4.set_figheight(5)
fig4.set_figwidth(15)
plt.show()
Machine Learning 1: Produktgruppenbestimmung¶
In diesem Abschnitt soll ein Klassifikator trainiert werden, welcher anhand von Eingabemerkmalen, wie Breite, Höhe, Gewicht usw. das zugehörige Fahrzeugsegment (Produktgruppe) vorhersagt.
In diesem Teilversuch sollen als Eingabemerkmale die zuvor in numeric_features definierten Spalten und die nicht-numerischen Spalten Antrieb, Kraftstoffart, KSTA Motor verwendet werden. Die Zielvariable (Ausgabe) stellt die Spalte Produktgruppe dar.
Produktgrunppenspezifische Visualisierung¶
- Plotten Sie für die drei oben angegebenen nicht-numerischen Merkmale jeweils eine Produktgruppen-spezifische Häufigkeitsverteilung in der unten dargestellten Form.
df.groupby(['Produktgruppe', 'Antrieb']).size().unstack().plot(kind='barh',
stacked=True,
figsize=(10, 8),
title='Antrieb pro Produktgruppe',
xlabel='Anzahl')
<Axes: title={'center': 'Antrieb pro Produktgruppe'}, xlabel='Anzahl', ylabel='Produktgruppe'>
df.groupby(['Produktgruppe', 'Kraftstoffart']).size().unstack().plot(kind='barh',
stacked=True,
figsize=(10, 8),
title='Kraftstoffart pro Produktgruppe',
xlabel='Anzahl')
<Axes: title={'center': 'Kraftstoffart pro Produktgruppe'}, xlabel='Anzahl', ylabel='Produktgruppe'>
df.groupby(['Produktgruppe', 'KSTA Motor']).size().unstack().plot(kind='barh',
stacked=True,
figsize=(10, 8),
title='KSTA Motor pro Produktgruppe',
xlabel='Anzahl')
<Axes: title={'center': 'KSTA Motor pro Produktgruppe'}, xlabel='Anzahl', ylabel='Produktgruppe'>
- Plotten Sie für alle numerischen Merkmale jeweils einen Produktgruppen-spezifischen Boxplot in der unten dargestellten Form.
sns.boxplot(x="Neupreis Brutto",
y='Produktgruppe',
data=df,
orient='h',
hue='Produktgruppe',
palette='tab10').set_title('Neupreis Brutto pro Produktgruppe')
Text(0.5, 1.0, 'Neupreis Brutto pro Produktgruppe')
sns.boxplot(x="CCM",
y='Produktgruppe',
data=df,
orient='h',
hue='Produktgruppe',
palette='tab10').set_title('CCM pro Produktgruppe')
Text(0.5, 1.0, 'CCM pro Produktgruppe')
sns.boxplot(x="KW",
y='Produktgruppe',
data=df,
orient='h',
hue='Produktgruppe',
palette='tab10').set_title('KW pro Produktgruppe')
Text(0.5, 1.0, 'KW pro Produktgruppe')
sns.boxplot(x="HST PS",
y='Produktgruppe',
data=df,
orient='h',
hue='Produktgruppe',
palette='tab10').set_title('HST PS pro Produktgruppe')
Text(0.5, 1.0, 'HST PS pro Produktgruppe')
sns.boxplot(x="Anzahl der Türen",
y='Produktgruppe',
data=df,
orient='h',
hue='Produktgruppe',
palette='tab10').set_title('Anzahl der Türen pro Produktgruppe')
Text(0.5, 1.0, 'Anzahl der Türen pro Produktgruppe')
sns.boxplot(x="Leergewicht",
y='Produktgruppe',
data=df,
orient='h',
hue='Produktgruppe',
palette='tab10').set_title('Leergewicht pro Produktgruppe')
Text(0.5, 1.0, 'Leergewicht pro Produktgruppe')
sns.boxplot(x="Zuladung",
y='Produktgruppe',
data=df,
orient='h',
hue='Produktgruppe',
palette='tab10').set_title('Zuladung pro Produktgruppe')
Text(0.5, 1.0, 'Zuladung pro Produktgruppe')
sns.boxplot(x="Zulässiges GG",
y='Produktgruppe',
data=df,
orient='h',
hue='Produktgruppe',
palette='tab10').set_title('Zulässiges GG pro Produktgruppe')
Text(0.5, 1.0, 'Zulässiges GG pro Produktgruppe')
sns.boxplot(x="Länge",
y='Produktgruppe',
data=df,
orient='h',
hue='Produktgruppe',
palette='tab10').set_title('Länge pro Produktgruppe')
Text(0.5, 1.0, 'Länge pro Produktgruppe')
sns.boxplot(x="Breite",
y='Produktgruppe',
data=df,
orient='h',
hue='Produktgruppe',
palette='tab10').set_title('Breite pro Produktgruppe')
Text(0.5, 1.0, 'Breite pro Produktgruppe')
sns.boxplot(x="Höhe",
y='Produktgruppe',
data=df,
orient='h',
hue='Produktgruppe',
palette='tab10').set_title('Höhe pro Produktgruppe')
Text(0.5, 1.0, 'Höhe pro Produktgruppe')
sns.boxplot(x="CO2-Emissionen",
y='Produktgruppe',
data=df,
orient='h',
hue='Produktgruppe',
palette='tab10').set_title('CO2-Emissionen pro Produktgruppe')
Text(0.5, 1.0, 'CO2-Emissionen pro Produktgruppe')
- Erzeugen Sie mit plotly.express scatter() einen 2-dimensionalen Plot, in dem alle Fahrzeuge wie folgt dargestellt werden (pro Fahrzeug ein Marker):
- x-Achse:
Länge - y-Achse:
Höhe - Farbe des Markers:
Produktgruppe - Größe des Markers:
Leergewicht - Bei Mouse-Over soll für den jeweiligen Marker der entsprechende Wert von
Neupreis BruttoundHST-HT Benennungangezeigt werden.
# Der Scatter Plot wird in der HTML nicht angezeigt.
# Grund: Leider keine Ahnung.
# Um den Scatter Plot zu sehen, navigieren Sie in das Notebook und führen sie die Zellen bis zu dem Scatter Plot aus.
fig = px.scatter(df,
x='Länge',
y='Höhe',
color='Produktgruppe',
size='Leergewicht',
hover_data={'Neupreis Brutto': True,
'HST-HT Benennung': True},
title='Scatter Plot'
)
fig.show()
Data Encoding¶
- Categoriale Merkmale ohne Ordnungsrelation (=nominale Merkmale) müssen One-Hot-Encodiert werden. Führen Sie für die drei categorialen Merkmale ein One-Hot-Encoding mit dem scikit-learn LabelBinarizer durch.
def one_hot_encoding(lb, feature):
lb.fit(feature)
return lb.transform(list(feature))
lb = LabelBinarizer()
cat_features = ['Antrieb', 'Kraftstoffart', 'KSTA Motor']
for feature in cat_features:
cats = df[feature].value_counts().index
sep_cats = [i.strip() for i in cats]
cats_count = len(sep_cats)
ohe_values = one_hot_encoding(lb=lb, feature=df[feature])
for i in range(cats_count):
values_list = [j[i] for j in ohe_values]
df[f"{feature}_{sep_cats[i]}"] = values_list
- Fügen Sie die one-hot-encodierten Spalten mit den numerischen Spalten zusammen. Weisen Sie die entsprechende Eingabedatenmatrix einem 2-dimensionalen numpy-array
Xzu.
numeric_features = [i for i in df.columns.values if is_numeric_dtype(df[i]) == True]
X = df[numeric_features]
X
| Neupreis Brutto | CCM | KW | HST PS | Anzahl der Türen | Leergewicht | Zuladung | Zulässiges GG | Länge | Breite | Höhe | CO2-Emissionen | Antrieb_FA | Antrieb_A | Antrieb_HA | Kraftstoffart_D | Kraftstoffart_BS | Kraftstoffart_08 | Kraftstoffart_SP | Kraftstoffart_06 | Kraftstoffart_07 | Kraftstoffart_E | Kraftstoffart_10 | Kraftstoffart_25 | Kraftstoffart_09 | Kraftstoffart_26 | Kraftstoffart_B1 | Kraftstoffart_S | Kraftstoffart_BN | KSTA Motor_STANDARD ->D | KSTA Motor_STANDARD ->B | KSTA Motor_HYBRID ->B | KSTA Motor_HYBRID ->D | KSTA Motor_BI_CNG ->B | KSTA Motor_BI_LPG ->B | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 37962 | 1896 | 112 | 154 | 4 | 2211 | 905 | 2967.615635 | 4852 | 1849 | 2019 | 218.0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
| 1 | 45294 | 1990 | 110 | 148 | 4 | 2243 | 753 | 3061.848723 | 4859 | 1827 | 1938 | 218.0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
| 2 | 48675 | 1943 | 110 | 150 | 4 | 2282 | 768 | 3018.887414 | 4788 | 1823 | 1990 | 218.0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
| 3 | 47201 | 2013 | 110 | 153 | 4 | 1954 | 1007 | 3096.198902 | 4927 | 1952 | 1935 | 210.0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
| 4 | 49453 | 1945 | 112 | 152 | 4 | 1984 | 972 | 3068.590854 | 4916 | 1872 | 2026 | 210.0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 24189 | 48042 | 2036 | 172 | 235 | 5 | 1755 | 798 | 2674.077424 | 4756 | 1911 | 1779 | 158.0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
| 24190 | 48979 | 1974 | 180 | 241 | 5 | 1770 | 775 | 2599.765400 | 4605 | 1977 | 1738 | 162.0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
| 24191 | 50849 | 2018 | 177 | 240 | 5 | 1763 | 804 | 2546.332693 | 5033 | 2011 | 1592 | 153.0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
| 24192 | 52973 | 1968 | 182 | 238 | 5 | 1704 | 820 | 2504.075063 | 4795 | 1941 | 1602 | 153.0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
| 24193 | 55797 | 2019 | 179 | 239 | 5 | 1769 | 821 | 2558.819988 | 5022 | 1865 | 1771 | 162.0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
24194 rows × 35 columns
- Führen Sie auf die Zielvariable
Produktgruppeein Label-Encoding mit scikit-learn LabelEncoder aus. Weisen Sie diese Daten dem 1-dimensionalen numpy-arrayyzu.
le = LabelEncoder()
le.fit(df['Produktgruppe'])
lb_produktgruppe = le.transform(df['Produktgruppe'])
y = lb_produktgruppe
y
array([21, 21, 21, ..., 22, 22, 22])
Generate Training- and Testpartition¶
Benutzen Sie die scikit-learn Methode train_test_split() um X und y in einer Trainings- und Testpartition aufzuteilen. 30% der Daten soll für das Testen, 70% für das Training benutzt werden.
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
print(len(X))
print(len(X_train))
print(len(X_test))
print('-------------')
print(len(y))
print(len(y_train))
print(len(y_test))
24194 16935 7259 ------------- 24194 16935 7259
Decision Tree Training, Test and Evaluation¶
- Trainieren Sie einen Entscheidungsbaum mit den Trainingsdaten.
clf_dt = DecisionTreeClassifier(random_state=42)
clf_dt = clf_dt.fit(X_train, y_train)
- Wenden Sie den gelernten Entscheidungsbaum auf die Testdaten an.
clf_dt.predict(X_test)
array([26, 14, 8, ..., 25, 14, 27])
- Evaluieren Sie die Qualität des Entscheidungsbaumes indem Sie
- einen classification_report erzeugen.
y_true = y_test
y_pred = clf_dt.predict(X_test)
print(classification_report(y_true, y_pred))
precision recall f1-score support
0 0.79 0.82 0.80 92
1 0.92 0.92 0.92 86
2 0.79 0.81 0.80 117
3 0.96 0.73 0.83 33
4 0.81 0.88 0.84 67
5 0.64 0.63 0.64 68
6 0.91 0.85 0.88 468
7 0.69 0.68 0.68 622
8 0.68 0.70 0.69 481
9 0.70 0.78 0.74 9
10 0.61 0.61 0.61 18
11 0.86 0.86 0.86 106
12 0.51 0.49 0.50 41
13 0.96 0.97 0.96 287
14 0.87 0.88 0.88 1206
15 0.89 0.85 0.87 98
16 0.83 0.88 0.86 17
17 0.78 0.66 0.71 70
18 0.46 0.53 0.49 49
19 0.99 0.98 0.99 174
20 0.92 0.91 0.91 193
21 0.82 0.87 0.85 211
22 0.84 0.75 0.80 93
23 0.90 0.90 0.90 247
24 0.69 0.72 0.70 173
25 0.76 0.76 0.76 584
26 0.82 0.86 0.84 340
27 0.86 0.85 0.86 1309
accuracy 0.82 7259
macro avg 0.79 0.79 0.79 7259
weighted avg 0.82 0.82 0.82 7259
Antwort:
- Aus der Precision lässt sich erkennen, dass ein Großteil der Produktgruppen meistes richtig erkannt wird (
True-Postive). Allerdings werden Produktgruppen wie zum Beispiel der Kleinwagen, oder Kleintransporter/Pkw, öfter alsFalse-Positiveerkannt, alsTrue-Positive. - Aus dem Recall lässt sich der genaue Prozentwert der Treffer herauslesen.
- Die meisten werden tatsächlcih gut erkannt, bis auf den Pkw und den Kleinwagen
- Die Luxuslimousine und Sprinterklasse haben wenig
False-Negative
- F1-Score ist das harmonische Mittel aus Precision und Recall und bestätigt die bisherigen Annahmen
- die confusion matrix plotten.
cm = confusion_matrix(y_test, y_pred, labels=clf_dt.classes_)
disp = ConfusionMatrixDisplay(confusion_matrix=cm,
display_labels=clf_dt.classes_,)
fig, ax = plt.subplots(figsize=(20, 20))
disp.plot(ax=ax)
# Die Nummern auf den Axen entsprechen den Produktgruppen (labels)
<sklearn.metrics._plot.confusion_matrix.ConfusionMatrixDisplay at 0x1d2babfa820>
- Interpretieren Sie das Ergebnis.
Die Diagonale ist erkennbar, was auf True-Positive Werte hindeutet. Allerdings kommen bei ähnlichen Produktgruppen False-Postiv Werte raus.
Beipsiele:
- Der Coupé Mittelklasse und sport Coupé werden öfter als
False-Postiveerkannt, da diese ähnliche Bausgröße/Krafstoffverbrauch haben - Der LKW wird öfter mit dem Mini-Van und Van verwechselt
- Führen Sie eine 10-fache Kreuzvalidierung des Entscheidungsbaumes mit den Daten
Xundyaus. Interpretieren Sie das Ergebnis.
print(cross_val_score(clf_dt, X, y, cv=10))
[0.68636364 0.69380165 0.73057851 0.70454545 0.74369574 0.70442332 0.74121538 0.77180653 0.77139314 0.74245556]
Antwort:
Die 10-fache Kreuzvalidierung erzeugt 10 Partitionen des Datensatzes und trainiert 10 Mal den Decision Tree jeweils mit den Partitionen.
Dadurch wird der trainierte Decision Tree auf unterschiedlichen Partitionen gestestet.
Da wir eine Range ~9% haben, deutete es darauf hin, dass die unterschiedlichen Produktgruppen nicht gleich häufig im Datensatz vorkommen (Vermutung anhand der Abweichung).
- Bestimmen Sie die Wichtigkeit der Eingabemerkmale für die Klassifikationsaufgabe, indem Sie auf den in 1.) gelernten DecisionTree das Attribut
feature_importance_abfragen. Stellen Sie die Werte in einem Barplot dar.
clf_dt.feature_importances_
array([1.09398363e-01, 3.24803871e-02, 3.75496660e-02, 1.72638629e-02,
7.39412156e-02, 4.02930399e-02, 6.37606257e-02, 1.61026519e-01,
2.11923757e-01, 3.48432122e-02, 1.53880717e-01, 3.56139665e-02,
1.07886388e-02, 6.50683425e-04, 1.03486884e-02, 1.13149140e-04,
0.00000000e+00, 2.44709984e-05, 0.00000000e+00, 0.00000000e+00,
0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
1.42579649e-03, 1.18108211e-03, 0.00000000e+00, 0.00000000e+00,
1.13176742e-04, 1.09584658e-04, 1.23565353e-04, 9.24996706e-04,
6.52695327e-04, 8.57453503e-04, 7.10686262e-04])
bar_df = pd.DataFrame({
'feature': X.columns,
'value': clf_dt.feature_importances_
})
sns.barplot(bar_df, x="value", y="feature", orient='y').set_title('Relevanz der features')
Text(0.5, 1.0, 'Relevanz der features')
Random Forest Training, Test and Evaluation¶
Wiederholen Sie die Teilaufgaben 1. bis 5. des Entscheidungsbaums für einen Random Forest. Vergelichen Sie die Performance der beiden Verfahren.
clf_rf = RandomForestClassifier(random_state=42)
clf_rf.fit(X_train, y_train)
RandomForestClassifier(random_state=42)In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
RandomForestClassifier(random_state=42)
clf_rf.predict(X_test)
array([14, 14, 8, ..., 25, 14, 14])
y_pred = clf_rf.predict(X_test)
print(classification_report(y_test, y_pred))
precision recall f1-score support
0 0.91 1.00 0.95 92
1 0.94 0.98 0.96 86
2 0.99 0.95 0.97 117
3 0.97 0.97 0.97 33
4 0.98 0.90 0.94 67
5 0.78 0.46 0.57 68
6 0.94 0.95 0.95 468
7 0.88 0.82 0.85 622
8 0.82 0.88 0.85 481
9 0.75 0.67 0.71 9
10 0.81 0.72 0.76 18
11 0.93 0.94 0.93 106
12 0.91 0.51 0.66 41
13 0.99 1.00 0.99 287
14 0.96 0.97 0.96 1206
15 0.99 0.93 0.96 98
16 1.00 1.00 1.00 17
17 0.78 0.76 0.77 70
18 0.61 0.51 0.56 49
19 0.99 1.00 0.99 174
20 0.93 0.96 0.95 193
21 0.92 0.93 0.93 211
22 0.95 0.88 0.92 93
23 0.98 0.96 0.97 247
24 0.82 0.82 0.82 173
25 0.90 0.92 0.91 584
26 0.96 0.95 0.96 340
27 0.92 0.95 0.94 1309
accuracy 0.92 7259
macro avg 0.90 0.87 0.88 7259
weighted avg 0.92 0.92 0.92 7259
Antwort:
Die Ergebnisse haben sich im Vergleich zum Decision Tree deutlich verbessert.
Trotz dessen gibt es kleine Ausreißer wie Kleintransporter/Pkw und Kleinwagen, welche immernoch einen schlechten Wert vorweisen.
Ähnich lässt es sich aus der Cunfusion Matrix herauslesen. Die Accuracy wurde besser, jedoch nicht perfekt.
cm = confusion_matrix(y_test, y_pred, labels=clf_rf.classes_)
disp = ConfusionMatrixDisplay(confusion_matrix=cm,
display_labels=clf_rf.classes_,)
fig, ax = plt.subplots(figsize=(20,20))
disp.plot(ax=ax)
<sklearn.metrics._plot.confusion_matrix.ConfusionMatrixDisplay at 0x1d2bbee5070>
print(cross_val_score(clf_rf, X, y, cv=10))
[0.77396694 0.73677686 0.7785124 0.76322314 0.7875155 0.75196362 0.77552708 0.81976023 0.8284415 0.77635387]
Antwort:
Die Abweichung der Werte liegt wieder bei ~9%. Die Werte sind generell höher als beim Decision Tree, dass heißt der Random Forest ist besser angepasst.
clf_rf.feature_importances_
array([8.13880109e-02, 4.80132497e-02, 4.39856123e-02, 4.72735511e-02,
4.96036994e-02, 9.13182928e-02, 8.33262806e-02, 1.18075542e-01,
1.29651940e-01, 5.35136731e-02, 1.51794796e-01, 5.13812154e-02,
8.51171399e-03, 1.05259039e-02, 9.20814812e-03, 2.62434314e-04,
1.72253973e-04, 1.20345471e-03, 3.41593837e-05, 2.76598482e-04,
1.41195819e-04, 1.10484515e-05, 4.04012859e-06, 0.00000000e+00,
3.84054298e-03, 4.17056478e-03, 2.52443272e-04, 6.93397919e-07,
9.02322194e-04, 2.73222582e-04, 2.20562070e-04, 1.66307374e-03,
8.73149542e-04, 3.80388543e-03, 4.32272635e-03])
bar_df = pd.DataFrame({
'feature': X.columns,
'value': clf_rf.feature_importances_
})
sns.barplot(bar_df, x="value", y="feature", orient='y').set_title('Relevanz der features')
Text(0.5, 1.0, 'Relevanz der features')
Machine Learning 2: Schätzung der CO2-Emission¶
In diesem Teilversuch soll aus den Eingabemerkmalen
"CCM","HST PS", "Anzahl der Türen", "Leergewicht", "Zuladung", "Länge", "Breite", "Höhe"
die Zielvariable
CO2-Emissionen
geschätzt werden. Hierzu soll ein möglichst gutes Regressionsmodell trainiert werden.
co2_df = df[["CCM", "HST PS", "Anzahl der Türen", "Leergewicht", "Zuladung", "Länge", "Breite", "Höhe", "CO2-Emissionen"]]
co2_df.head()
| CCM | HST PS | Anzahl der Türen | Leergewicht | Zuladung | Länge | Breite | Höhe | CO2-Emissionen | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 1896 | 154 | 4 | 2211 | 905 | 4852 | 1849 | 2019 | 218.0 |
| 1 | 1990 | 148 | 4 | 2243 | 753 | 4859 | 1827 | 1938 | 218.0 |
| 2 | 1943 | 150 | 4 | 2282 | 768 | 4788 | 1823 | 1990 | 218.0 |
| 3 | 2013 | 153 | 4 | 1954 | 1007 | 4927 | 1952 | 1935 | 210.0 |
| 4 | 1945 | 152 | 4 | 1984 | 972 | 4916 | 1872 | 2026 | 210.0 |
Visuelle Korrelationsanalyse¶
- Stellen Sie für jedes der 8 Eingabemerkmale die Korrelation mit der Zielvariablen visuell in einem Scatterplot dar, in dem das jeweilige Eingabemerkmal auf der x-Achse und die Zielvariable auf der y-Achse aufgetragen wird.
px.scatter(co2_df,
x='CCM',
y='CO2-Emissionen',
title='CCM im Vergleich zur CO2-Emissionen')
px.scatter(co2_df,
x='HST PS',
y='CO2-Emissionen',
title='HST PS im Vergleich zur CO2-Emissionen')
px.scatter(co2_df,
x='Anzahl der Türen',
y='CO2-Emissionen',
title='Anzahl der Türen im Vergleich zur CO2-Emissionen')
px.scatter(co2_df,
x='Leergewicht',
y='CO2-Emissionen',
title='Leergewicht im Vergleich zur CO2-Emissionen')
px.scatter(co2_df,
x='Zuladung',
y='CO2-Emissionen',
title='Zuladung im Vergleich zur CO2-Emissionen')
px.scatter(co2_df,
x='Länge',
y='CO2-Emissionen',
title='Länge im Vergleich zur CO2-Emissionen')
px.scatter(co2_df,
x='Breite',
y='CO2-Emissionen',
title='Breite im Vergleich zur CO2-Emissionen')
px.scatter(co2_df,
x='Höhe',
y='CO2-Emissionen',
title='Höhe im Vergleich zur CO2-Emissionen')
- Diskutieren Sie die Korrelationen. Welche Merkmale korrelieren am stärksten mit der Zielvariable? Erscheint Ihnen das plausibel?
Antwort:
- Anzahl der Türen erscheint nutzlos
- Am stärksten koorelieren CCM und HST PS, da diese direkt mit dem Spritverbrauch korrelieren
- Länge und Breite korrleiren einigermaßen mit der Zielvariable, weil ein längeres und breiteres Auto in der Regel mehr wiegt und somit einen höhren Spritverbrauch haben
- Auch in Hinsicht auf den Luftwiderstand bei der Form/Länge/Breite des Wagens
Data Encoding¶
- Weisen Sie die Matrix der Eingabedaten dem 2-dimensionalen Array
Xund die Zielvariable dem 1-dimensionalen Arrayyzu.
X2 = co2_df.iloc[:, :-1]
y2 = co2_df.iloc[:, -1:]
X2.head()
| CCM | HST PS | Anzahl der Türen | Leergewicht | Zuladung | Länge | Breite | Höhe | |
|---|---|---|---|---|---|---|---|---|
| 0 | 1896 | 154 | 4 | 2211 | 905 | 4852 | 1849 | 2019 |
| 1 | 1990 | 148 | 4 | 2243 | 753 | 4859 | 1827 | 1938 |
| 2 | 1943 | 150 | 4 | 2282 | 768 | 4788 | 1823 | 1990 |
| 3 | 2013 | 153 | 4 | 1954 | 1007 | 4927 | 1952 | 1935 |
| 4 | 1945 | 152 | 4 | 1984 | 972 | 4916 | 1872 | 2026 |
y2.head()
| CO2-Emissionen | |
|---|---|
| 0 | 218.0 |
| 1 | 218.0 |
| 2 | 218.0 |
| 3 | 210.0 |
| 4 | 210.0 |
- Führen Sie auf
Xundyeine Partitionierung in Trainings- und Testdaten durch, wieder im Verhältnis 70/30.
X2_train, X2_test, y2_train, y2_test = train_test_split(X2, y2, test_size=0.3, random_state=42)
print(len(X2))
print(len(X2_train))
print(len(X2_test))
print('-------------')
print(len(y2))
print(len(y2_train))
print(len(y2_test))
24194 16935 7259 ------------- 24194 16935 7259
- Skalieren Sie die Eingabevariablen und die Zielvariable mit dem MinMaxScaler. Die Skalierung muss sowohl auf Trainings- als auch auf Testdaten ausgeführt werden. Warum darf die Skalierung erst nach dem Split in die beiden Partitionen ausgeführt werden? Worauf ist zu achten?
scaler = MinMaxScaler()
scaler.fit(X2_train)
X2_train = scaler.transform(X2_train)
scaler.fit(X2_test)
X2_test = scaler.transform(X2_test)
scaler.fit(y2_train)
y2_train = scaler.transform(y2_train)
scaler.fit(y2_test)
y2_test = scaler.transform(y2_test)
X2_train
array([[0.20017021, 0.14678899, 1. , ..., 0.38978801, 0.53058954,
0.14650027],
[0.10978723, 0.08256881, 1. , ..., 0.39092774, 0.46162403,
0.15626696],
[0.37565957, 0.28134557, 1. , ..., 0.51766583, 0.57063404,
0.13944655],
...,
[0.06808511, 0.12538226, 0. , ..., 0.33781628, 0.35261402,
0.15084102],
[0.19574468, 0.19877676, 1. , ..., 0.38933212, 0.42714127,
0.13347802],
[0.18757447, 0.14678899, 1. , ..., 0.40323684, 0.46718576,
0.35485621]])
X2_test
array([[0.20633227, 0.20760697, 0.66666667, ..., 0.60474205, 0.43112245,
0.16330166],
[0.20330843, 0.2614897 , 1. , ..., 0.50807712, 0.40433673,
0.1543943 ],
[0.12628958, 0.07131537, 1. , ..., 0.54247004, 0.56505102,
0.40973872],
...,
[0.2997154 , 0.16323296, 1. , ..., 0.51328817, 0.46556122,
0.30047506],
[0.12860192, 0.16006339, 0.66666667, ..., 0.53673788, 0.4375 ,
0.12767221],
[0.1638207 , 0.09825674, 1. , ..., 0.54637832, 0.47321429,
0.13776722]])
y2_train
array([[0.28442728],
[0.2046332 ],
[0.34877735],
...,
[0.26640927],
[0.28700129],
[0.34877735]])
y2_test
array([[0.26933333],
[0.336 ],
[0.23733333],
...,
[0.28266667],
[0.25066667],
[0.26666667]])
Antwort:
- Man will in jeder Partition (Training und Test) jeweils eine Skala von 0 bis 1 haben
- Wenn man vor der Partition skalieren würde, könnte man nicht garantieren, dass beide Partitionen eine Skala von 0 bis 1 haben
Training, Test und Evaluation verschiedener Regressionsmodelle¶
Führen Sie die folgenden Teilaufgaben sowohl für ein Single Layer Perceptron als auch für ein Multi Layer Perceptron mit 20 Neuronen in der Hidden-Schicht durch. Vergleichen Sie am Ende die Performance der beiden Verfahren.
def determineRegressionMetrics(y_test,y_pred,title=""):
mse = mean_squared_error(y_test, y_pred)
mad = mean_absolute_error(y_test, y_pred)
rmsle=np.sqrt(mean_squared_error(np.log(y_test+1),np.log(y_pred+1)))# +1 for avoiding log(0)
r2=r2_score(y_test, y_pred)
med=median_absolute_error(y_test, y_pred)
print(title)
print("Mean absolute error =", round(mad, 2))
print("Mean squared error =", round(mse, 2))
print("Median absolute error =", round(med, 2))
print("R2 score =", round(r2, 2))
print("Root Mean Squared Logarithmic Error =",rmsle)
Single Layer Perceptron¶
- Trainieren Sie den Algorithmus mit den Trainingsdaten.
reg_sl = SGDRegressor(random_state=42)
reg_sl.fit(X2_train, y2_train)
C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\utils\validation.py:1184: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().
SGDRegressor(random_state=42)In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
SGDRegressor(random_state=42)
- Wenden Sie das gelernte Modell auf die Testdaten an.
reg_sl.predict(X2_test)
array([0.35401494, 0.3427621 , 0.33877106, ..., 0.3649114 , 0.32096766,
0.31535955])
Multilayer Perceptron¶
- Trainieren Sie den Algorithmus mit den Trainingsdaten.
- Wenden Sie das gelernte Modell auf die Testdaten an.
reg_ml = MLPRegressor(random_state=42, hidden_layer_sizes=20)
reg_ml.fit(X2_train, y2_train)
C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().
MLPRegressor(hidden_layer_sizes=20, random_state=42)In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
MLPRegressor(hidden_layer_sizes=20, random_state=42)
reg_ml.predict(X2_test)
array([0.24598485, 0.25035327, 0.29124764, ..., 0.31398969, 0.21079277,
0.19297961])
Vergleich¶
- Evaluieren Sie die Qualität der Modelle, indem Sie auf die vorhergesagten Ausgaben und die wahren Ausgaben die unten gegebene Funktion aufrufen.
single_metrics = determineRegressionMetrics(y_test=y2_test, y_pred=reg_sl.predict(X2_test))
Mean absolute error = 0.05 Mean squared error = 0.01 Median absolute error = 0.05 R2 score = 0.28 Root Mean Squared Logarithmic Error = 0.05707240761003042
multi_metrics = determineRegressionMetrics(y_test=y2_test, y_pred=reg_ml.predict(X2_test))
Mean absolute error = 0.06 Mean squared error = 0.01 Median absolute error = 0.05 R2 score = 0.22 Root Mean Squared Logarithmic Error = 0.05935435700780056
Antwort:
- Die Modelle liefern sehr geringe Fehlerwerte und somit einen sehr guten Wert bei der Predictoin
- Die Ergebnisse der verschiedenen Metriken weichen nur minimal voneinander ab. Somit liefern die beiden Ansätze (Single Layer Perceptron und Multi Layer Perceptron) die gleichen Ergebnisse
- Beschreiben Sie kurz die in der Funktion verwendeten Metriken
Mean Absolute Error: It measures the average absolute difference between the predicted values and the actual target values
Mean Squared Error: It calculates the average of the squares of the errors
Median Absolute Error: It calculates the median between the predicted values and the actual target values
R2 Score: R² kann zwischen 0 un 1 liegen. Es erklärt wie gut ein Modell die Varianz der abhängigen Variablen erklärt.
Root Mean Squared Logarithmis Error: It calculates the average of the squares of the errors, but focuse more on the error count and less on the values of the erros
Hyperparameteroptimierung¶
Für ein Multi Layer Perceptron soll eine Hyperparameteroptimierung durchgeführt werden. Ziel ist es innerhalb der unten vorgegebenen Wertebereiche für die Hyperparameter hidden_layer_sizes, activation und learning_rate die beste Konfiguration zu finden. Hierzu kann entweder GridSearchCV oder RandomizedSearchCV eingesetzt werden. GridSearchCV testet einfach alle Konfigurationen durch, benötigt daher aber viel Zeit. RandomizedSearchCV geht heuristisch und damit schneller durch den Suchraum. Wenden Sie eines dieser beiden Verfahren an, um für das unten gegebene Parameter-Grid die optimale Konfiguration zu finden. Welches ist die optimale Konfiguration und zu welchem neg_mean_absolute_error führt diese wenn man das scoring argument der Funktion entsprechend einstellt?
regr = MLPRegressor(random_state=42)
param_grid = [{'hidden_layer_sizes': [(10,),(20,),(30,),(40,),(50,),(100,),(10,10)],
'activation': ["logistic", "tanh", "relu"],
'learning_rate': ["constant", "invscaling", "adaptive"]}]
rs_m = RandomizedSearchCV(regr, param_distributions=param_grid, scoring='neg_mean_absolute_error')
# Die Fehlermeldungen bitte ignorieren
rs_m.fit(X2_train, y2_train)
C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel(). C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\neural_network\_multilayer_perceptron.py:1625: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().
RandomizedSearchCV(estimator=MLPRegressor(random_state=42),
param_distributions=[{'activation': ['logistic', 'tanh',
'relu'],
'hidden_layer_sizes': [(10,), (20,),
(30,), (40,),
(50,), (100,),
(10, 10)],
'learning_rate': ['constant',
'invscaling',
'adaptive']}],
scoring='neg_mean_absolute_error')In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
RandomizedSearchCV(estimator=MLPRegressor(random_state=42),
param_distributions=[{'activation': ['logistic', 'tanh',
'relu'],
'hidden_layer_sizes': [(10,), (20,),
(30,), (40,),
(50,), (100,),
(10, 10)],
'learning_rate': ['constant',
'invscaling',
'adaptive']}],
scoring='neg_mean_absolute_error')MLPRegressor(random_state=42)
MLPRegressor(random_state=42)
rs_m.best_params_
{'learning_rate': 'invscaling',
'hidden_layer_sizes': (100,),
'activation': 'relu'}
rs_m.best_score_
-0.03770788148445644
Antwort:
Beim neg_mean_absolute_error deutet ein Wert, der näher an Null liegt (also ein kleinerer negativer Wert), auf eine bessere Modellleistung hin.
- Data Selection and Encoding
co2_df_h = df[["Getriebeart", "CCM", "HST PS", "Anzahl der Türen", "Leergewicht", "Zuladung", "Länge", "Breite", "Höhe", "CO2-Emissionen"]]
lb.fit(co2_df_h['Getriebeart'])
co2_df_h['Getriebeart'] = lb.transform(co2_df_h['Getriebeart'])
C:\Users\paulv\AppData\Local\Temp\ipykernel_166776\1582940501.py:2: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
co2_df_h
| Getriebeart | CCM | HST PS | Anzahl der Türen | Leergewicht | Zuladung | Länge | Breite | Höhe | CO2-Emissionen | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 1896 | 154 | 4 | 2211 | 905 | 4852 | 1849 | 2019 | 218.0 |
| 1 | 1 | 1990 | 148 | 4 | 2243 | 753 | 4859 | 1827 | 1938 | 218.0 |
| 2 | 1 | 1943 | 150 | 4 | 2282 | 768 | 4788 | 1823 | 1990 | 218.0 |
| 3 | 1 | 2013 | 153 | 4 | 1954 | 1007 | 4927 | 1952 | 1935 | 210.0 |
| 4 | 1 | 1945 | 152 | 4 | 1984 | 972 | 4916 | 1872 | 2026 | 210.0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 24189 | 0 | 2036 | 235 | 5 | 1755 | 798 | 4756 | 1911 | 1779 | 158.0 |
| 24190 | 0 | 1974 | 241 | 5 | 1770 | 775 | 4605 | 1977 | 1738 | 162.0 |
| 24191 | 0 | 2018 | 240 | 5 | 1763 | 804 | 5033 | 2011 | 1592 | 153.0 |
| 24192 | 0 | 1968 | 238 | 5 | 1704 | 820 | 4795 | 1941 | 1602 | 153.0 |
| 24193 | 0 | 2019 | 239 | 5 | 1769 | 821 | 5022 | 1865 | 1771 | 162.0 |
24194 rows × 10 columns
- Visuelle Korrelation
px.scatter(co2_df_h,
x='Getriebeart',
y='CO2-Emissionen',
title='Getriebeart im Vergleich zur CO2-Emissionen')
- Train Test Split
X_h = co2_df_h.iloc[:, :-1]
y_h = co2_df_h.iloc[:, -1:]
X_h_train, X_h_test, y_h_train, y_h_test = train_test_split(X_h, y_h, test_size=0.3, random_state=42)
- Data Scaling
scaler.fit(X_h_train)
X_h_train = scaler.transform(X_h_train)
scaler.fit(X_h_test)
X_h_test = scaler.transform(X_h_test)
scaler.fit(y_h_train)
y_h_train = scaler.transform(y_h_train)
scaler.fit(y_h_test)
y_h_test = scaler.transform(y_h_test)
- Training des Singel Layer Perceptron
reg_sl_h = SGDRegressor(random_state=42)
reg_sl_h.fit(X_h_train, y_h_train)
C:\Users\paulv\anaconda3\envs\DataMining\lib\site-packages\sklearn\utils\validation.py:1184: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().
SGDRegressor(random_state=42)In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
SGDRegressor(random_state=42)
reg_sl_h.predict(X_h_test)
array([0.35361514, 0.34203285, 0.33950959, ..., 0.36436785, 0.32152107,
0.31572454])
single_metrics_h = determineRegressionMetrics(y_test=y_h_test, y_pred=reg_sl_h.predict(X_h_test))
Mean absolute error = 0.05 Mean squared error = 0.01 Median absolute error = 0.05 R2 score = 0.28 Root Mean Squared Logarithmic Error = 0.05704888332794298
Anwort:
Die Hypothese wurde widerlegt.
Das Hinzufügen des Getriebetyps zu den Daten für das Training des Single Layer Perceptrons verbesser NICHT die Ausgaben bei der Prediction der CO2-Emissionen. Tatsächlich steigt nur der Root Mean Squard Logarithmic Error um lediglich 0.00003, was keine Relevanz hat.
Damit tritt auch die Nullhypothese ein die besagt: "Das Hinzufügen des Getriebetypes bei dem Singel Layer Percteptron führt zu keiner Verbesserung der Ausgaben bei der Prediction der CO2-Emissionen."
Ein Hinweis auf das Endergebniss ergab sich bereits aus der visuellen Korrelationsanalyse, welche keine besonderen Korrelationen darstellte.